﻿using HighThroughput.ShareData;
using Newtonsoft.Json;
using Ozone.BLL;
using Ozone.Device;
using Ozone.Help;
using Ozone.Models.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Media.Animation;

namespace Ozone.Common
{
    public class RadisService
    {



        //关于RedisKey创建规则
        //1: 安装业务流程创建执行Key: 如机械臂执行动作 创建机械臂执行动作Key 
        //   如配液不需要把配液的设备都创建Key  直接创建执行配液逻辑Key即可，按照业务逻辑拆分单元去创建
        //2: 每一个执行Key都必须有一个相对应的状态返回值 Key
        //3: 起一个异步心跳Key 用于证明Redis还正常
        //4: 单独设备状态 Key 根据情况创建






        /// <summary>
        ///  设置RadisKey中的值
        /// </summary>
        /// <param name="KeyName"></param>
        /// <param name="KeyValue"></param>
        /// <returns></returns>
        public static async Task<bool> SetKeyValueAsync(string KeyName, string KeyValue)
        {
            bool IsSuccess = false;
            try
            {
                IsSuccess = await DeviceCenter.redisKeyWatcher.SetKeyValueAsync(KeyName, KeyValue);
            }
            catch (Exception ex)
            {
                LogHelper.Error("设置RadisKey中的值", ex);
                IsSuccess = false;
            }
            return IsSuccess;
        }


        /// <summary>
        /// 判断Key值是否存在
        /// </summary>
        /// <param name="KeyName"></param>
        /// <returns></returns>
        public static bool KeyExists(string KeyName)
        {
            bool IsSuccess = false;
            try
            {
                IsSuccess = DeviceCenter.redisKeyWatcher.KeyExists(KeyName);
            }
            catch (Exception ex)
            {
                LogHelper.Error("判断RadisKey值是否存在异常抛出：", ex);

                IsSuccess = false;
            }

            return IsSuccess;
        }

        /// <summary>
        /// 监控到Key值发生了变化
        /// </summary>
        /// <param name="KeyName"></param>
        public static void KeyChange(string KeyName)
        {
            try
            {

                string Message = string.Empty;
                //监控到Key值发生变化
                if (!string.IsNullOrEmpty(KeyName))
                {
                    if (KeyName == ("RadisHeartbeat"))
                    {
                        //心跳 直接返回
                        return;
                    }
                    else if (KeyName == ("DeviceWorkLog"))
                    {
                        string KeyValue = GetKeyValueAsync(KeyName).Result;
                        if (KeyValue != null && !string.IsNullOrEmpty(KeyValue))
                        {

                            OperLogBLL.AddLogAndShowPage(KeyValue);

                        }
                        Process1ViewModel.Instance.WorkerStats_YTJY = true;
                    }
                    else if (KeyName == ("PageNUmber"))
                    {
                        LogHelper.Debug("检测到RedisKey,DeviceWorkLog更新,显示到页面!");
                        string KeyValue = GetKeyValueAsync(KeyName).Result;
                        if (KeyValue != null && !string.IsNullOrEmpty(KeyValue))
                        {

                            //ReadData.Entity.HeatingPumpFlow = KeyValue;

                        }
                    }
                }
            }
            catch (Exception ex)
            {

                LogHelper.Error("监控Key值发生了变化异常抛出：", ex);
            }

        }







        public static async Task<string> GetKeyValueAsync(string KeyName)
        {
            string KeyValue = string.Empty;
            try
            {
                KeyValue = await DeviceCenter.redisKeyWatcher.GetKeyValueAsync(KeyName);

            }
            catch (Exception ex)
            {
                KeyValue = string.Empty;
                LogHelper.Error("设置RadisKey值异常抛出：", ex);
            }

            return KeyValue;
        }











        /// <summary>
        ///设置Key对应执行状态
        /// 例如 机械臂A抓取移动到B 监控是否执行完成
        /// </summary>
        /// <param name="MonitorKey">监控Key名称</param>
        /// <param name="MonitorValue">监控Key值</param>
        /// <param name="Intervaltime">轮询间隔时间(s)</param>
        /// <param name="TimeOut">超时时间(s)</param>
        /// <param name="Message"></param>
        /// <returns></returns>
        public static bool SetKeyExecutionStatus(string MonitorKey, string MonitorValue, out string Message, int Intervaltime = 2, int TimeOut = 1200)
        {
            bool IsExecutionOk = false;
            try
            {
                int ExecutionTime = 0;
                while (true)
                {
                    //获取监控Key值
                    string KeyValue = GetKeyValueAsync(MonitorKey).Result;
                    if (KeyValue == MonitorValue)
                    {
                        Message = "执行成功";
                        //执行成功
                        IsExecutionOk = true;
                        break;
                    }
                    Thread.Sleep(Intervaltime * 1000);
                    ExecutionTime = ExecutionTime + Intervaltime;

                    if (ExecutionTime > TimeOut)
                    {
                        Message = "执行超时";
                        //执行成功
                        IsExecutionOk = false;
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error("等待Key执行动作时异常", ex);
                Message = "捕获异常";
            }
            return IsExecutionOk;

        }



        /// <summary>
        /// 异步监控键值状态
        /// </summary>
        /// <param name="monitorKey">监控键名</param>
        /// <param name="targetValue">目标键值</param>
        /// <param name="intervalMs">轮询间隔(毫秒，默认2000)</param>
        /// <param name="timeoutMs">超时时间(毫秒，默认1200000)</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>包含执行状态和消息的元组</returns>
        public static async Task<(bool IsSuccess, string Message)>
            MonitorKeyValueAsync(
                string monitorKey,
                string targetValue,
                int intervalMs = 2000,
                int timeoutMs = 1200000,
                CancellationToken cancellationToken = default)
        {
            try
            {
                var startTime = DateTime.UtcNow;

                while (!cancellationToken.IsCancellationRequested)
                {
                    // 异步获取键值
                    string currentValue = await GetKeyValueAsync(monitorKey);

                    if (currentValue == targetValue)
                    {
                        return (true, "执行成功");
                    }

                    // 检查超时
                    if ((DateTime.UtcNow - startTime).TotalMilliseconds > timeoutMs)
                    {
                        return (false, $"操作超时({timeoutMs}ms)");
                    }

                    // 异步等待间隔时间
                    await Task.Delay(intervalMs, cancellationToken);
                }

                return (false, "操作被取消");
            }
            catch (OperationCanceledException)
            {
                return (false, "监控操作已取消");
            }
            catch (Exception ex)
            {
                // 记录完整异常信息
                LogHelper.Error("等待Key执行动作时异常", ex);
                return (false, $"监控异常: {ex.Message}");
            }
        }



        #region  起一个心跳服务确保Redis一直正常运行
        private readonly TimeSpan _interval = TimeSpan.FromSeconds(10);
        private readonly CancellationTokenSource _cts = new CancellationTokenSource();
        private Task _heartbeatTask;
        public void Start()
        {
            _heartbeatTask = Task.Factory.StartNew(
                () => HeartbeatLoopAsync(_cts.Token),
                _cts.Token,
                TaskCreationOptions.LongRunning,
                TaskScheduler.Default);
        }

        private async Task HeartbeatLoopAsync(CancellationToken ct)
        {
            try
            {
                Thread.CurrentThread.Priority = ThreadPriority.Highest;
                while (!ct.IsCancellationRequested)
                {
                    string guid = Guid.NewGuid().ToString();
                    try
                    {
                        await RadisService.SetKeyValueAsync("RadisHeartbeat", guid);
                        LogHelper.Debug("RadisHeartbeat心跳更新值：" + guid);
                    }
                    catch (Exception ex)
                    {
                        LogHelper.Error("Redis更新RadisHeartbeat失败：", ex);
                    }

                    await Task.Delay(_interval, ct);
                }
            }
            catch (OperationCanceledException)
            {
                // 正常退出
            }
            catch (Exception ex)
            {
                LogHelper.Error("Redis心跳服务异常终止：", ex);

            }
        }

        /// <summary>
        /// 停止Redis心跳复位
        /// </summary>
        /// <returns></returns>
        public async Task StopAsync()
        {
            _cts.Cancel();
            await (_heartbeatTask ?? Task.CompletedTask);
        }
        /// <summary>
        /// 释放心跳线程
        /// </summary>
        public void Dispose()
        {
            _cts.Dispose();
            GC.SuppressFinalize(this);
        }
        #endregion



    }
}
